home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / sysdeps / mach / hurd / i386 / exc2signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-08  |  3.9 KB  |  166 lines

  1. /* Translate Mach exception codes into signal numbers.  i386 version.
  2. Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. #include <hurd.h>
  21. #include <hurd/signal.h>
  22. #include <mach/exception.h>
  23.  
  24. /* Translate the Mach exception codes, as received in an `exception_raise' RPC,
  25.    into a signal number and signal subcode.  */
  26.  
  27. void
  28. _hurd_exception2signal (int exception, int code, int subcode,
  29.             int *signo, int *sigcode, int *error)
  30. {
  31.   *error = 0;
  32.  
  33.   switch (exception)
  34.     {
  35.     default:
  36.       *signo = SIGIOT;
  37.       *sigcode = exception;
  38.       break;
  39.       
  40.     case EXC_BAD_ACCESS:
  41.       if (code == KERN_PROTECTION_FAILURE)
  42.     *signo = SIGSEGV;
  43.       else
  44.     *signo = SIGBUS;
  45.       *sigcode = subcode;
  46.       *error = code;
  47.       break;
  48.  
  49.     case EXC_BAD_INSTRUCTION:
  50.       *signo = SIGILL;
  51.       if (code == EXC_I386_INVOP)
  52.     *sigcode = ILL_INVOPR_FAULT;
  53.       else if (code == EXC_I386_STKFLT)
  54.     *sigcode = ILL_STACK_FAULT;
  55.       else
  56.     *sigcode = 0;
  57.       break;
  58.       
  59.     case EXC_ARITHMETIC:
  60.       switch (code)
  61.     {
  62.     case EXC_I386_DIV:    /* integer divide by zero */
  63.       *signo = SIGFPE;
  64.       *sigcode = FPE_INTDIV_FAULT;
  65.       break;
  66.       
  67.     case EXC_I386_INTO:    /* integer overflow */
  68.       *signo = SIGFPE;
  69.       *sigcode = FPE_INTOVF_TRAP;
  70.       break;
  71.  
  72.       /* These aren't anywhere documented or used in Mach 3.0.  */
  73.     case EXC_I386_NOEXT:
  74.     case EXC_I386_EXTOVR:
  75.     default:
  76.       *signo = SIGFPE;
  77.       *sigcode = 0;
  78.       break;
  79.  
  80.     case EXC_I386_EXTERR:
  81.       /* Subcode is the fp_status word saved by the hardware.
  82.          Give an error code corresponding to the first bit set.  */
  83.       if (subcode & FPS_IE)
  84.         {
  85.           *signo = SIGILL;
  86.           *sigcode = ILL_FPEOPR_FAULT;
  87.         }
  88.       else if (subcode & FPS_DE)
  89.         {
  90.           *signo = SIGFPE;
  91.           *sigcode = FPE_FLTDNR_FAULT;
  92.         }
  93.       else if (subcode & FPS_ZE)
  94.         {
  95.           *signo = SIGFPE;
  96.           *sigcode = FPE_FLTDIV_FAULT;
  97.         }
  98.       else if (subcode & FPS_OE)
  99.         {
  100.           *signo = SIGFPE;
  101.           *sigcode = FPE_FLTOVF_FAULT;
  102.         }
  103.       else if (subcode & FPS_UE)
  104.         {
  105.           *signo = SIGFPE;
  106.           *sigcode = FPE_FLTUND_FAULT;
  107.         }
  108.       else if (subcode & FPS_PE)
  109.         {
  110.           *signo = SIGFPE;
  111.           *sigcode = FPE_FLTINX_FAULT;
  112.         }
  113.       else
  114.         {
  115.           *signo = SIGFPE;
  116.           *sigcode = 0;
  117.         }
  118.       break;
  119.  
  120.       /* These two can only be arithmetic exceptions if we 
  121.          are in V86 mode, which sounds like emulation to me.
  122.          (See Mach 3.0 i386/trap.c.)  */
  123.     case EXC_I386_EMERR:
  124.       *signo = SIGFPE;
  125.       *sigcode = FPE_EMERR_FAULT;
  126.       break;
  127.     case EXC_I386_BOUND:
  128.       *signo = SIGFPE;
  129.       *sigcode = FPE_EMBND_FAULT;
  130.       break;
  131.     }
  132.       break;
  133.  
  134.     case EXC_EMULATION:        
  135.       /* 3.0 doesn't give this one, why, I don't know.  */
  136.       *signo = SIGEMT;
  137.       *sigcode = 0;
  138.       break;
  139.  
  140.     case EXC_SOFTWARE:
  141.       /* The only time we get this in Mach 3.0
  142.      is for an out of bounds trap.  */
  143.       if (code == EXC_I386_BOUND)
  144.     {
  145.       *signo = SIGFPE;
  146.       *sigcode = FPE_SUBRNG_FAULT;
  147.     }
  148.       else
  149.     {
  150.       *signo = SIGEMT;
  151.       *sigcode = 0;
  152.     }
  153.       break;
  154.       
  155.     case EXC_BREAKPOINT:
  156.       *signo = SIGTRAP;
  157.       if (code == EXC_I386_SGL)
  158.     *sigcode = DBG_SINGLE_TRAP;
  159.       else if (code == EXC_I386_BPT)
  160.     *sigcode = DBG_BRKPNT_FAULT;
  161.       else
  162.     *sigcode = 0;
  163.       break;
  164.     }
  165. }
  166.